package com.wnxy.pms.product.core.job;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wnxy.pms.product.core.constant.PromotionStatus;
import com.wnxy.pms.product.core.constant.RedisConstant;
import com.wnxy.pms.product.core.entity.PromotionSeckill;
import com.wnxy.pms.product.core.service.IProductService;
import com.wnxy.pms.product.core.service.IPromotionSeckillService;
import com.wnxy.pms.product.core.vo.PromotionProductVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class PromotionJob {

    @Autowired
    private IProductService productService;
    @Autowired
    private IPromotionSeckillService promotionSeckillService;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 需求：5秒执行一次
     * 任务调度表达式： 秒 分钟 小时  日  月 周
     * 注意：
     *      日与周有一个为？，表示不指定，避免冲突
     *
     * cron = "* * * * * *  每秒执行
     * cron = "1-10 * * * * *   每分钟的第1-10秒执行
     * cron = "1,2 * * * * *   每分钟的第1,2秒执行
     * cron = "0/5 * * * * *   每分钟的第1,2秒执行
     *
     */
    @Scheduled(cron = "0/10 * 12 * * ?")
    public void execute(){
        //需求：查询秒杀商品列表，放入缓存。
        //1. 查询秒杀商品，查询条件：A、秒杀时间已经到达; B、秒杀活动未开始，状态为0
        List<PromotionProductVo> list =
                productService.findPromotionSeckillByStatus(PromotionStatus.WAIT_STATUS);
        //2. 判断
        if (!CollectionUtils.isEmpty(list)) {
            //2.1 把查询的秒杀商品放入redis缓存
            // String PRODUCT_SECKILL = "product:seckill";
            redisTemplate.opsForList().leftPushAll(RedisConstant.PRODUCT_SECKILL,list);

            // 初始化库存到redis中
            initStore();

            //2.2 修改秒杀商品的状态，改为1，表示活动已开始
            // UPDATE pms_promotion_seckill SET STATUS=0 WHERE id IN (1,2,3,4,5,6,11)
            //2.2.1 先获取要修改的id集合
            List<Integer> idList = list.stream()
                    .map(PromotionProductVo::getPromotionId)
                    .collect(Collectors.toList());
            //2.2.2 再修改秒杀商品
            LambdaUpdateWrapper<PromotionSeckill> wrapper =
                    Wrappers.lambdaUpdate(PromotionSeckill.class);
            wrapper.set(PromotionSeckill::getStatus,PromotionStatus.START_STATUS);
            wrapper.in(PromotionSeckill::getId,idList);
            promotionSeckillService.update(wrapper);

        }
    }

    /**
     * 初始化库存，通过redis存储
     */
    private void initStore(){
        //1. 查询所有时间已到，且秒杀活动未开始的数据
        List<Map<String,Object>> list =
                promotionSeckillService.selectStoreByStatus(PromotionStatus.WAIT_STATUS);
        //2. 判断
        if (!CollectionUtils.isEmpty(list)) {
            //3. 遍历, 把查询的库存放入redis
            list.forEach(temp->{
                //获取秒杀活动id、商品id、库存
                Integer promotionId = (Integer) temp.get("promotionId");
                Integer productId = (Integer) temp.get("productId");
                Integer count = (Integer) temp.get("count");
                log.info("秒杀活动ID：{},商品ID：{}，库存：{}",promotionId,productId,count);
                for (int i = 0; i < count; i++) {
                    redisTemplate.opsForList().leftPush(
                            RedisConstant.SECKILL_COUNT+promotionId,productId);
                }
            });
        }
    }
}
